import random

from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django_redis import get_redis_connection

from utils import my_email
from utils.encrypt import md5
from web import models


# 使用Form组件，需要定义类
class LoginForm(forms.Form):
    role = forms.ChoiceField(
        label='角色',
        choices=(('2', '客户'), ('1', '管理员',)),
        widget=forms.Select(attrs={'name': "role", 'class': "form-control"}))
    # <input name="username" type="text" class="form-control" id="inputText3" placeholder="用户名">#
    username = forms.CharField(
        label='用户名',
        widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': '用户名'}))
    password = forms.CharField(
        # form校验一，字段内部校验，4个字段方法
        # required=True,  # 默认是True，可以不写
        # validators=[RegexValidator(r'^[\d]+$', '密码必须是数字'), ],  # 正则表达式
        # max_length=16,
        # min_length=8,

        label='密码',
        widget=forms.PasswordInput(attrs={'class': "form-control", 'placeholder': '密码'}, render_value=True))

    def clean_password(self):
        return md5(self.cleaned_data.get('password'))

    def clean(self):
        pass

    def _post_clean(self):
        pass


class SmsLoginForm(forms.Form):
    role = forms.ChoiceField(
        label='角色',
        choices=(('2', '客户'), ('1', '管理员',)),
        widget=forms.Select(attrs={'name': "role", 'class': "form-control"}))
    mobile = forms.CharField(
        label='手机号',
        validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号码格式错误'), ],
        widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': '手机号'}))
    code = forms.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '验证码必须是数字'), ],  # 数字字符串
        label='短信验证码',
        widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': '短信验证码'}))

    def clean_code(self):
        # 2. 短信验证码校验
        mobile = self.cleaned_data.get('mobile')
        code = self.cleaned_data['code']
        if not mobile:
            return code

        conn = get_redis_connection('default')
        cache_code = conn.get(mobile)
        if not cache_code:
            raise ValidationError('验证码未发送或已失效')
        if code != cache_code.decode('utf-8'):
            raise ValidationError('验证码错误')

        return code


class EmailLoginForm(forms.Form):
    role = forms.ChoiceField(
        label='角色',
        choices=(('2', '客户'), ('1', '管理员',)),
        widget=forms.Select(attrs={'name': "role", 'class': "form-control"}))
    email = forms.EmailField(
        label='邮箱',
        widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': '邮箱'}))
    code = forms.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '验证码必须是数字'), ],  # 数字字符串
        label='验证码',
        widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': '验证码'}))

    def clean_code(self):
        # 邮箱是否已注册
        role = self.cleaned_data.get('role')
        email = self.cleaned_data.get('email')
        if role == "1":
            exists = models.Administrator.objects.filter(email=email, active=1).exists()
        else:
            exists = models.Customer.objects.filter(email=email, active=1).exists()
        if not exists:
            raise ValidationError("邮箱未注册")

        # 2. 验证码校验
        code = self.cleaned_data.get('code')
        if not email:
            return code

        conn = get_redis_connection('default')
        cache_code = conn.get(email)
        if not cache_code:
            raise ValidationError('验证码未发送或已失效')
        if code != cache_code.decode('utf-8'):
            raise ValidationError('验证码错误')

        return code


class mobileForm(forms.Form):
    role = forms.ChoiceField(
        label='角色',
        choices=(('2', '客户'), ('1', '管理员',)),
        widget=forms.Select(attrs={'name': "role", 'class': "form-control"}))
    mobile = forms.CharField(
        validators=[RegexValidator(r'^1[3578]\d{9}$', '手机号码格式错误'), ],
    )


class emailForm(forms.Form):
    role = forms.ChoiceField(
        label='角色',
        choices=(('2', '客户'), ('1', '管理员',)),
        widget=forms.Select(attrs={'name': "role", 'class': "form-control"}))
    email = forms.EmailField()

    def clean_email(self):
        # 邮箱是否已注册
        role = self.cleaned_data.get('role')
        email = self.cleaned_data['email']
        if role == "1":
            exists = models.Administrator.objects.filter(email=email, active=1).exists()
        else:
            exists = models.Customer.objects.filter(email=email, active=1).exists()
        if not exists:
            raise ValidationError("邮箱未注册")

        # 2. 生成验证码，发送邮件
        email_code = str(random.randint(1000, 9999))
        is_success = my_email.send_mail(email, email_code)
        if not is_success:
            raise ValidationError("发送失败")

        # 3. 保存邮箱和验证码到缓存，方便下次使用。
        conn = get_redis_connection('default')
        conn.set(email, email_code, ex=600)  # 验证码有效期10min

        return email
